package net.maergaiyun.component;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import net.maergaiyun.config.WechatPayApi;
import net.maergaiyun.config.WechatPayConfig;
import net.maergaiyun.util.CommonUtil;
import net.maergaiyun.vo.PayInfoVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信支付
 */
@Service
@Slf4j
public class WechatPayStrategy implements PayStrategy {
    @Autowired
    private WechatPayConfig wechatPayConfig;

    @Autowired
    private RestTemplate restTemplate;

    public static final HttpHeaders headers = new HttpHeaders();

    static {
        headers.setContentType(MediaType.APPLICATION_JSON);
    }

    /**
     * 微信支付下单
     *
     * @param payInfoVO
     * @return
     */
    @Override
    public String unifiedOrder(PayInfoVO payInfoVO) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
        String timeExpire = simpleDateFormat.format(new Date(System.currentTimeMillis() + payInfoVO.getOrderPayTimeoutMills()));

        JSONObject amountObj = new JSONObject();
        int amount = payInfoVO.getPayFee().multiply(BigDecimal.valueOf(100)).intValue();
        // 订单金额, 单位为分
        amountObj.put("total", amount);
        amountObj.put("currency", "CNY");


        JSONObject payObj = new JSONObject();

        payObj.put("mchid", wechatPayConfig.getMchId());
        payObj.put("out_trade_no", payInfoVO.getOutTradeNo());
        payObj.put("appid", wechatPayConfig.getWxPayAppid());
        payObj.put("description", payInfoVO.getTitle());
        payObj.put("notify_url", wechatPayConfig.getCallbackUrl());

        payObj.put("time_expire", timeExpire);
        payObj.put("amount", amountObj);
        // 附加参数, 用在回调
        payObj.put("attach", "{\"accountNo\":" + payInfoVO.getAccountNo() + "}");

        String body = payObj.toJSONString();

        HttpEntity<String> entity = new HttpEntity<>(body, headers);
        String result = "";
        try {
            ResponseEntity<String> response = restTemplate.exchange(WechatPayApi.NATIVE_ORDER, HttpMethod.POST, entity, String.class);
            int statusCode = response.getStatusCodeValue();
            String responseStr = response.getBody().toString();

            if (statusCode == HttpStatus.OK.value()) {
                JSONObject jsonObject = JSONObject.parseObject(responseStr);
                if (jsonObject.containsKey("mchid")) {
                    result = jsonObject.getString("mchid");
                }
            } else {
                log.error("下单响应失败, 响应体: {}", responseStr);
            }
        } catch (Exception e) {
            log.error("下单异常: {}", e.toString());
        }
        return result;
    }

    @Override
    public String refund(PayInfoVO payInfoVO) {
        return PayStrategy.super.refund(payInfoVO);
    }

    /**
     * 微信支付查询订单状态
     *
     * @param payInfoVO
     * @return
     */
    @Override
    public String queryPayStatus(PayInfoVO payInfoVO) {
        String outTradeNo = payInfoVO.getOutTradeNo();
        JSONObject payObj = new JSONObject();
        payObj.put("mchid", wechatPayConfig.getMchId());
        payObj.put("out_trade_no", outTradeNo);
        String body = payObj.toJSONString();
        HttpEntity<String> entity = new HttpEntity<>(body, headers);
        String result = "";
        try {
            ResponseEntity<String> response = restTemplate.exchange(WechatPayApi.NATIVE_ORDER_QUERY, HttpMethod.POST, entity, String.class);
            int statusCode = response.getStatusCodeValue();
            String responseStr = response.getBody().toString();
            if (statusCode == HttpStatus.OK.value()) {
                JSONObject jsonObject = JSONObject.parseObject(responseStr);
                if (jsonObject.containsKey("trade_state")) {
                    result = jsonObject.getString("trade_state");
                }
            } else {
                log.error("查询支付状态响应失败: {}", responseStr);
            }
        } catch (Exception e) {
            log.error("微信支付响应异常: {}", e.toString());
        }
        return result;
    }

    /**
     * 微信支付关闭订单
     *
     * @param payInfoVO
     * @return
     */
    @Override
    public String closeOrder(PayInfoVO payInfoVO) {
        String outTradeNo = payInfoVO.getOutTradeNo();

        JSONObject payObj = new JSONObject();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        payObj.put("mchid", wechatPayConfig.getMchId());
        payObj.put("out_trade_no", outTradeNo);

        String body = payObj.toJSONString();

        HttpEntity<String> entity = new HttpEntity<>(body, headers);
        String result = "";
        try {
            ResponseEntity<String> response = restTemplate.exchange(WechatPayApi.NATIVE_ORDER_CLOSE, HttpMethod.POST, entity, String.class);
            int statusCode = response.getStatusCodeValue();
            if (statusCode == HttpStatus.NO_CONTENT.value()) {
                result = "CLOSE_SUCCESS";
            } else {
                log.error("微信关闭订单失败");
            }
        } catch (Exception e) {
            log.error("微信支付响应异常: {}", e.toString());
        }
        return result;
    }
}
